gusucode.com > 各种VC自绘控件源码程序 > 各种VC自绘控件源码/code/SkinControls(自绘MFC基本控件 )/SkinControls/SkinControls/SkinTreeCtrl.cpp
#include "stdafx.h" #include "SkinTreeCtrl.h" #include "MemDC.h" ////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC(CSkinTreeCtrl, CTreeCtrl) BEGIN_MESSAGE_MAP(CSkinTreeCtrl, CTreeCtrl) ON_WM_PAINT() ON_WM_SIZE() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_ERASEBKGND() ON_NOTIFY_REFLECT(NM_CLICK, OnNMClick) ON_WM_HSCROLL() ON_WM_VSCROLL() ON_WM_MOUSEWHEEL() ON_WM_MBUTTONUP() ON_NOTIFY_REFLECT(NM_DBLCLK, OnNMDblclk) END_MESSAGE_MAP() ////////////////////////////////////////////////////////////////////////// CSkinTreeCtrl::CSkinTreeCtrl() { m_crGradient = RGB(64,154,191); m_crSelected = RGB(54,96,96); m_crNormalText = RGB(0,0,0); m_crSelectedText = RGB( 255, 255, 255 ); m_crBackground = RGB(255,255,255); m_crLineColor = RGB(0,0,0); m_hItemSelect = NULL; m_hItemMouseMove = NULL; m_ptOldMouse.x = -1; m_ptOldMouse.y = -1; } CSkinTreeCtrl::~CSkinTreeCtrl() { } void CSkinTreeCtrl::PreSubclassWindow() { SetItemHeight(25); CRect rcClient; GetClientRect(&rcClient); m_HorOffset = rcClient.left; m_HorSize = rcClient.Width(); m_VorOffset = rcClient.top; m_VorSize = rcClient.Height(); CTreeCtrl::PreSubclassWindow(); } void CSkinTreeCtrl::OnSize(UINT nType, int cx, int cy) { CTreeCtrl::OnSize(nType, cx, cy); Calculate(); } void CSkinTreeCtrl::OnPaint() { CPaintDC dc(this); CRect rcClient; GetClientRect(&rcClient); CMemDC BufferDC(&dc, &rcClient); BufferDC.FillSolidRect(&rcClient, m_crBackground); DrawItem(&BufferDC); } void CSkinTreeCtrl::Calculate() { CRect rcClient; GetClientRect(&rcClient); SCROLLINFO scroll_info; if ( GetScrollInfo( SB_HORZ, &scroll_info, SIF_POS | SIF_RANGE ) ) { m_HorOffset = -scroll_info.nPos; m_HorSize = max( scroll_info.nMax+1, rcClient.Width()); } else { m_HorOffset = rcClient.left; m_HorSize = rcClient.Width(); } if ( GetScrollInfo( SB_VERT, &scroll_info, SIF_POS | SIF_RANGE ) ) { if ( scroll_info.nMin == 0 && scroll_info.nMax == 100) scroll_info.nMax = 0; m_VorOffset = -scroll_info.nPos * GetItemHeight(); m_VorSize = max( (scroll_info.nMax+2)*((int)GetItemHeight()+1), rcClient.Height() ); } else { m_VorOffset = rcClient.top; m_VorSize = rcClient.Height(); } } void CSkinTreeCtrl::GradientFillRect( CDC *pDC, CRect & rc, COLORREF crTopLeft, COLORREF crBottomRight, bool bVerGrad ) { TRIVERTEX vert[2]; GRADIENT_RECT mesh; vert[0].x = rc.left; vert[0].y = rc.top; vert[0].Alpha = 0x0000; vert[0].Blue = GetBValue(crTopLeft) << 8; vert[0].Green = GetGValue(crTopLeft) << 8; vert[0].Red = GetRValue(crTopLeft) << 8; vert[1].x = rc.right; vert[1].y = rc.bottom; vert[1].Alpha = 0x0000; vert[1].Blue = GetBValue(crBottomRight) << 8; vert[1].Green = GetGValue(crBottomRight) << 8; vert[1].Red = GetRValue(crBottomRight) << 8; mesh.UpperLeft = 0; mesh.LowerRight = 1; pDC->GradientFill( vert, 2, &mesh, 1, bVerGrad ? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H ); } void CSkinTreeCtrl::DrawItem( CDC *pDC ) { HTREEITEM hCurrentItem = NULL, hParentItem = NULL; CRect rcItem; DWORD dwTreeStyle; int nState = 0; bool bSelected = false; BOOL bHasChildren = FALSE; hCurrentItem = GetFirstVisibleItem(); if ( hCurrentItem == NULL ) return; dwTreeStyle = ::GetWindowLong( m_hWnd, GWL_STYLE ); do { nState = GetItemState( hCurrentItem, TVIF_STATE ); hParentItem = GetParentItem( hCurrentItem ); bHasChildren = ItemHasChildren( hCurrentItem )/* || hParentItem == NULL*/; bSelected = (nState & TVIS_SELECTED) && ((this == GetFocus()) || (dwTreeStyle & TVS_SHOWSELALWAYS)); if ( GetItemRect( hCurrentItem, &rcItem, TRUE ) ) { CRect rcClient; GetClientRect(rcClient); if (rcItem.top >= rcClient.bottom) { break; //不可见的时候,就不需要再绘制 } CRect rect; rect.top = rcItem.top; rect.bottom = rcItem.bottom-1; rect.right = m_HorSize + m_HorOffset; rect.left = m_HorOffset; CPen pen(PS_SOLID, 1, m_crLineColor); pDC->SelectObject(&pen); pDC->MoveTo(rect.left,rect.bottom); pDC->LineTo(rect.right, rect.bottom); if ( bSelected ) { GradientFillRect( pDC, rect, m_crSelected, m_crSelected, FALSE ); } else if ( m_hItemMouseMove == hCurrentItem ) { GradientFillRect( pDC, rect, m_crGradient, m_crGradient, FALSE ); } if ( bHasChildren ) { DrawExpand(rcItem,nState,pDC); } ///////////如果ITEM不需要图片的话就直接画TEXT了,后面的那一部分就可以不要了/////////////////////////// ////绘制文本 //DrawItemText(rcItem,hCurrentItem,bSelected,pDC); ////////////////////////////////////////////////////////////////////////// //这个地方在其他地方用的话应该稍微修改一下,我这个地方就直接写的了,懒得做功能函数了 CImageList * pImageList = NULL; pImageList = GetImageList(LVSIL_NORMAL); int nImage, nSelectedImage; BOOL b = GetItemImage(hCurrentItem, nImage, nSelectedImage); if (pImageList != NULL && b == TRUE) { pImageList->Draw(pDC, nImage, CPoint(rcItem.left, rcItem.top), ILD_TRANSPARENT); CRect rc = rcItem; rc.left = rcItem.left + 16 +2; //rc.right = rc.left + rcItem.Width(); rc.right = m_HorSize; //绘制文本 DrawItemText(rc,hCurrentItem,bSelected,pDC); } else { CRect rc = rcItem; rc.right = m_HorSize; //绘制文本 DrawItemText(rc,hCurrentItem,bSelected,pDC); } } } while ( (hCurrentItem = GetNextVisibleItem( hCurrentItem )) != NULL ); } void CSkinTreeCtrl::DrawExpand(CRect rcRect, int nState, CDC * pDC) { CPoint point; point.x = rcRect.left - m_ImagePlusMinus.GetWidth()/2 - 4; point.y = rcRect.top + (rcRect.Height() - m_ImagePlusMinus.GetHeight())/2; if ( nState & TVIS_EXPANDED ) //展开 { m_ImagePlusMinus.Draw(pDC->m_hDC, point.x, point.y, m_ImagePlusMinus.GetWidth()/2, m_ImagePlusMinus.GetHeight(), m_ImagePlusMinus.GetWidth()/2, 0, m_ImagePlusMinus.GetWidth()/2, m_ImagePlusMinus.GetHeight()); } else //收缩 { m_ImagePlusMinus.Draw(pDC->m_hDC, point.x, point.y, m_ImagePlusMinus.GetWidth()/2, m_ImagePlusMinus.GetHeight(), 0, 0, m_ImagePlusMinus.GetWidth()/2, m_ImagePlusMinus.GetHeight()); } } void CSkinTreeCtrl::DrawItemText(CRect rcRect, HTREEITEM hItem, bool bSelected,CDC * pDC) { CString strText = GetItemText( hItem ); pDC->SetBkMode(TRANSPARENT); UINT uFormat=DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS; CFont font; font.CreateFont(-12,0,0,0,400,0,0,0,134,3,2,1,2,TEXT("宋体")); pDC->SelectObject(&font); if (bSelected) pDC->SetTextColor(m_crSelectedText); else pDC->SetTextColor(m_crNormalText); pDC->DrawText(strText,&rcRect,uFormat); } void CSkinTreeCtrl::OnMouseMove(UINT nFlags, CPoint point) { CTreeCtrl::OnMouseMove(nFlags, point); m_ptOldMouse = point; HTREEITEM hItem = HitTest(point); if ( hItem != NULL && hItem != m_hItemMouseMove ) { CRect rcItem; if (m_hItemMouseMove != NULL) GetItemRect(m_hItemMouseMove, &rcItem, FALSE); m_hItemMouseMove = hItem; InvalidateRect(&rcItem, FALSE); if (m_hItemMouseMove != NULL) GetItemRect(m_hItemMouseMove, &rcItem, FALSE); InvalidateRect(&rcItem, FALSE); } } void CSkinTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point) { CTreeCtrl::OnLButtonDown(nFlags, point); UINT uFlags = 0; HTREEITEM hItem = HitTest(point, &uFlags); if(hItem == NULL) return; SelectItem(hItem); if (!(uFlags & TVHT_ONITEMBUTTON)) Expand(hItem, TVE_TOGGLE); } BOOL CSkinTreeCtrl::OnEraseBkgnd(CDC* pDC) { return TRUE; } void CSkinTreeCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult) { Invalidate(); *pResult = 0; } void CSkinTreeCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { Invalidate(); CTreeCtrl::OnHScroll(nSBCode, nPos, pScrollBar); } void CSkinTreeCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { Invalidate(); CTreeCtrl::OnVScroll(nSBCode, nPos, pScrollBar); } BOOL CSkinTreeCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { Invalidate(); return FALSE; } void CSkinTreeCtrl::OnMButtonUp(UINT nFlags, CPoint point) { Invalidate(); CTreeCtrl::OnMButtonUp(nFlags, point); } void CSkinTreeCtrl::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult) { Invalidate(); *pResult = 0; } void CSkinTreeCtrl::SetPlusMinusImage(LPCTSTR pszFileName, DWORD imagetype) { ASSERT(pszFileName != NULL); if (pszFileName == NULL) return; m_ImagePlusMinus.Load(pszFileName,imagetype); } void CSkinTreeCtrl::SetPlusMinusImage(HRSRC hRes, DWORD imagetype, HMODULE hModule) { m_ImagePlusMinus.LoadResource(hRes,imagetype, hModule); } //////////////////////////////////////////////////////////////////////////